"""
Grave! Important! Важно!

Proletoj el ĉiuj landoj, unuiĝu!
Workers of the world, unite!
Пролетарии всех стран, соединяйтесь!

https://tkom.pro
"""

import io
import copy
import mimetypes
from io import BytesIO
from PIL import Image
from django.core.files.uploadedfile import SimpleUploadedFile, UploadedFile, InMemoryUploadedFile
from django.core.files.base import ContentFile


def get_pil_type(uploaded_image):
    if len(Image.SAVE):
        pil_type = uploaded_image.content_type.split('/')[1].upper() \
            if uploaded_image.content_type.split('/')[1].upper() in Image.SAVE else None
    else:
        pil_type = uploaded_image.content_type.split('/')[1].upper() \
            if uploaded_image.content_type.split('/')[1].upper() in ['JPEG', 'PNG', 'GIF'] else None

    return pil_type


def get_web_image(uploaded_image):
    """
    Функция преобразует загруженное изображение в RGB
    с палитрой WEB
    """
    if isinstance(uploaded_image, UploadedFile) \
            and uploaded_image.content_type.split('/')[0] == 'image':

        pil_type = get_pil_type(uploaded_image)

        if pil_type is not None:
            file = (copy.deepcopy(uploaded_image.file) if isinstance(uploaded_image, InMemoryUploadedFile)
                    else uploaded_image.file)
            image = Image.open(BytesIO(file.read()))
            image = image.convert("RGB", colors="WEB")

            # Сохраняем результат в памяти
            image_format = uploaded_image.content_type.split('/')[1].upper()
            opts = {}

            if image_format == 'JPEG':
                opts['progressive'] = True
                opts['quality'] = 85
            elif image_format == 'PNG':
                opts['optimize'] = True

            out_handle = BytesIO()
            image.save(out_handle, pil_type, **opts)
            out_handle.seek(0)

            # Преобразуем в SimpleUploadedFile и возвращаем
            out = SimpleUploadedFile('web_%s' % (uploaded_image.name), out_handle.read(),
                                     uploaded_image.content_type, )

            return out

    return None


def get_thumbnail(uploaded_image, size=(50, 50)):
    """
    Функция преобразует загруженное изображение в миниатюру
    и возвращает объект SimpleUploadedFile в качестве результата.
    Если переданные параметры не корректны, то возвращает None
    """
    if isinstance(uploaded_image, UploadedFile) \
            and uploaded_image.content_type.split('/')[0] == 'image':
        pil_type = get_pil_type(uploaded_image)

        if pil_type is not None:
            file = (copy.deepcopy(uploaded_image.file) if isinstance(uploaded_image, InMemoryUploadedFile)
                    else uploaded_image.file)
            image = Image.open(BytesIO(file.read()))
            image.thumbnail(size, Image.ANTIALIAS)

            # Сохраняем результат в памяти
            out_handle = BytesIO()
            image.save(out_handle, pil_type)
            out_handle.seek(0)

            # Преобразуем в SimpleUploadedFile и возвращаем
            out = SimpleUploadedFile('thumb_%s' % (uploaded_image.name), out_handle.read(),
                                     uploaded_image.content_type, )

            return out

    return None


def get_image_resize(uploaded_image, size=(50, 50)):
    """
    Функция преобразует загруженное изображение в миниатюру
    и возвращает объект SimpleUploadedFile в качестве результата.
    Если переданные параметры не корректны, то возвращает None
    """
    if isinstance(uploaded_image, UploadedFile) \
            and uploaded_image.content_type.split('/')[0] == 'image':

        pil_type = get_pil_type(uploaded_image)

        if pil_type is not None:
            file = (copy.deepcopy(uploaded_image.file) if isinstance(uploaded_image, InMemoryUploadedFile)
                    else uploaded_image.file)
            image = Image.open(BytesIO(file.read()))
            image = image.resize(size, Image.ANTIALIAS)

            # Сохраняем результат в памяти
            out_handle = BytesIO()
            image.save(out_handle, pil_type)
            out_handle.seek(0)

            # Преобразуем в SimpleUploadedFile и возвращаем
            out = SimpleUploadedFile('thumb_%s' % (uploaded_image.name), out_handle.read(),
                                     uploaded_image.content_type, )

            return out

    return None


def get_image_properties(uploaded_image):
    """
    Функция возвращает свойства загруженного изображения в виде словаря
    !!!!!!!
    Пока только ширину, высоту и формат
    !!!!!!!
    """
    if isinstance(uploaded_image, UploadedFile) \
            and uploaded_image.content_type.split('/')[0] == 'image':

        pil_type = get_pil_type(uploaded_image)

        if pil_type is not None:
            file = (copy.deepcopy(uploaded_image.file) if isinstance(uploaded_image, InMemoryUploadedFile)
                    else uploaded_image.file)
            image = Image.open(BytesIO(file.read()))
            properties = {'width': image.width, 'height': image.height, 'format': image.format}

            return properties
    return None


def get_thumbnail_content(file, size=(50, 50), path=None, suffix=None):
    image = Image.open(file).copy()
    pil_type = image.format or (
        file.content_type if hasattr(file, 'content_type') else mimetypes.guess_type(file.name)[0]
    ).split('/')[1].upper()
    image.thumbnail(size, Image.ANTIALIAS)
    raw = io.BytesIO()
    image.save(raw, pil_type)
    raw.seek(0)

    content = ContentFile(raw.read())

    if path:
        content.name = (
            path if not suffix
            else "{}_{}.{}".format(
                path.split('.')[0],
                suffix,
                path.split('.')[-1]
            )
        )

    return content
